import { Directive, Injector, ViewChild } from '@angular/core';
import { ApiTableResponse } from '@basic';
import { STColumn, STComponent, STReq, STRes } from '@delon/abc/st';
import { SFComponent, SFSchema } from '@delon/form';
import { deepGet } from '@delon/util';
import format from 'date-fns/format';

import { BaseOfSimpleComponent } from './abstract-simple-component.base';

/**
 * 根据url请求单页数据，后台翻页
 */
@Directive()
export abstract class UrlOfSimpleTable extends BaseOfSimpleComponent {
    @ViewChild('st', { static: false })
    st!: STComponent;

    @ViewChild('sf', { static: false })
    sf!: SFComponent;

    /**
     * 页面的搜索条件缓存
     */
    tableSearchParams: any = {};

    protected constructor(protected override injector: Injector) {
        super(injector);
    }

    // 请求数据的参数
    params: any = {};

    // 请求的地址
    abstract url: string;

    // 表格渲染数据
    abstract columns: STColumn[];

    // 搜索框渲染条件
    abstract searchSchema: SFSchema;

    // 重命名请求参数
    get reqReName(): STReq {
        return {
            reName: {
                pi: 'pageNum',
                ps: 'pageSize'
            },
            method: 'GET',
            params: this.params
        };
    }

    // 匹配返回的结果
    resReName: STRes = {
        reName: {
            total: 'total',
            list: 'rows'
        }
    };

    // 根据时间条件获取数据
    getDataByDate(st: STComponent, data: any): void {
        const params = { ...this.params, ...data };
        st.reset(params);
    }

    // 重置表格的搜索事件
    reSetDataGet(event: any): void {
        this.st.reset(event);
    }

    /**
     * 参数处理
     * @param {*} params  参数
     */
    tansParams(params: any) {
        for (const propName of Object.keys(params)) {
            const value = params[propName];
            if (value !== null && value !== '' && typeof value !== 'undefined') {
                if (typeof value === 'object') {
                    for (const key of Object.keys(value)) {
                        if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') {
                            let _params = `${propName}[${key}]`;
                            params[_params] = value[key];
                        }
                    }
                } else {
                    params[propName] = value;
                }
            }
        }
        delete params.params;
        return params;
    }
    // 根据条件搜索数据
    searchDataGet(event: any): void {
        if (event.range) {
            event['params[beginTime]'] = `${event.range[0].substring(0, 10)} 00:00:00`;
            event['params[endTime]'] = `${event.range[1].substring(0, 10)} 23:59:59`;
            delete event.range;
        }
        this.st.reset(event);
    }

    /**
     * ST导出选中项
     */
    simpleTableExportCheckedItems(fileName: string = 'File Name', sheetName: string = 'sheet name'): void {
        this.exportTableData(this.multipleCheckedItems, fileName, sheetName);
    }

    /**
     * ST导出所有数据
     */
    simpleTableExportAllItems(fileName: string = 'File Name', sheetName: string = 'sheet name'): void {
        this.client
            .post(this.url, {
                page: 1,
                pageSize: this.st.total,
                queryFilter: this.st.req.body && this.st.req.body.queryFilter ? this.st.req.body.queryFilter : this.tableSearchParams
            })
            .subscribe((res: ApiTableResponse) => {
                if (res.rows) {
                    this.exportTableData(res.rows, fileName, sheetName);
                }
            });
    }

    private exportTableData(tableData: any[], fileName: string = 'File Name', sheetName: string = 'sheet name'): void {
        const data = [
            this.columns
                .filter(a => a.exported !== false)
                .map((i: any) => {
                    if (i.title instanceof Object) {
                        return i.title.text + i.title.optional;
                    } else {
                        return i.title;
                    }
                })
        ];
        // 格式化菜单内容
        tableData.forEach(i =>
            data.push(
                this.columns
                    .filter(a => a.exported !== false)
                    .map((c: any) => {
                        if (c.format) {
                            return c.format(i);
                        }
                        const value = deepGet(i, c.index as string, '');
                        if (value !== 0 && !value) {
                            return null;
                        }
                        if (c.type && c.type === 'tag') {
                            return c.tag[value].text;
                        }
                        if (c.type && c.type === 'badge') {
                            return c.badge[value].text;
                        }
                        if (c.type && c.type === 'date') {
                            if (isNaN(value)) {
                                return value;
                            }
                            return format(value, 'yyyy-MM-dd HH:mm:ss');
                        }
                        return value;
                    })
            )
        );
        this.xlsx.export({
            sheets: [
                {
                    data,
                    name: sheetName
                }
            ],
            filename: `${fileName}_${new Date().toLocaleDateString('zh-CN')}-${new Date().toTimeString()}.xlsx`
        });
    }

    exportExcelByGet(url: string): void {
        const getParams = this.parseParams(this.tableSearchParams);
        window.open(`${url}?${getParams}`);
    }
}
